home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Online
/
PortScanner
/
portscanner.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-25
|
11KB
|
322 lines
/***********************************************************/
/* PORTSCANNER.C by Tennessee Carmel-Veilleux */
/* Contact info: (I speak french and english :) */
/* e-mail: veilleux@ameth.org */
/* www: http://www.ameth.org/~veilleux */
/* */
/* Version 1.2 */
/* The author of this program offers no waranty at all */
/* about the correct execution of this software material. */
/* Furthermore, the author can NOT be held responsible for */
/* any physical or moral damage caused by the use of this */
/* software. */
/* */
/* -> This program will scan for TCP ports listening on a */
/* remote or local host inside the range you give to it.*/
/* I offer no warranty over the accuracy though :) */
/* There are 3 verbose modes: No info, service info, and*/
/* full info. No info is good of you only want the list */
/* of the ports, no more info. The best mode is Full */
/* info, as you get error information,etc. The main */
/* output is STDOUT, and ALL the errors go to STDERR. */
/* */
/* History: v1.0 : August 9 1998 -> First release */
/* v1.2 : August 19 1998 -> Major release */
/***********************************************************/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/time.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define VERSION "1.2"
int sock = -1; /* Main socket */
struct sockaddr_in address, address2; /* Address structure */
struct sockaddr *sub_address; /* Address in subnet */
int result; /* Temporary results for operations */
u_short current_port = 0; /* Current port being scanned */
u_short base_port = 1; /* Base port to start scanning from */
u_short end_port = 1024; /* Port number to end scanning at */
u_char start_address = 1; /* Subnet address to start at */
u_char end_address = 254; /* Subnet address to finish at */
int verbose = 0; /* Level of verbosity */
struct hostent *host_info; /* Host information structure */
struct servent *service_info; /* Service information structure */
char addr[1024]; /* Address to connect to, 1024 chars max */
int strobe = 0; /* 1 if we want strobe scanning */
int subnet = 0; /* 1 if we want subnet scanning */
int i; /* Counter variable */
void port_scan(void);
void print_usage(int finish);
void print_help(int finish);
void print_info(int finish);
void print_usage(int finish) {
fprintf(stderr,
"Usage: portscan [-b start] [-e end] [-bm start] [-em end] [-v[v]] [-a] [-s] [-i] [-? | h] <address>\n");
if (finish)
exit(1);
}
void print_help(int finish) {
print_usage(0);
fprintf(stderr,"\n-b start: Specify the port at which we begin scanning\n");
fprintf(stderr,"-e end: Specify the port at which we stop scanning\n");
fprintf(stderr,"-bm: Subnet machine number at which to start scanning [dfl=1]\n");
fprintf(stderr,"-em: Subnet machine number at which to stop scanning [dfl=254]\n");
fprintf(stderr,"-v: Level 1 of verbosity, basic information\n");
fprintf(stderr,"-vv: Level 2 of verbosity, full information report\n");
fprintf(stderr,"-a: if we want subnet scanning (start at .1, end at .254)\n");
fprintf(stderr,"-s: strobe scanning: scan only ports found in /etc/services, much faster\n");
fprintf(stderr,"-? or -h: print this help text\n");
fprintf(stderr,"-i: Copyright and version information\n");
if (finish) exit(1);
}
void print_info(int finish) {
fprintf(stderr,"portscanner v%s was written by Tennessee Carmel-Veilleux\n",VERSION);
fprintf(stderr,"This version compiled on %s at %sEST\n",__DATE__,__TIME__);
fprintf(stderr,"This program is licensed under the GPL. See www.gnu.org for more info on the license\n");
if (finish) exit(1);
}
int main(int argc, char **argv)
{
if (argc < 2) {
print_usage(1);
}
switch (argc) {
case 2: if (!strcmp(argv[1],"-i")) {
print_info(1);
} else if ((!strcmp(argv[1],"-?")) || (!strcmp(argv[1],"-h"))) {
print_help(1);
} else {
break;
}
default: for (i = 1; i < argc - 1; i++) {
if (!strcmp(argv[i],"-v")) {
verbose = 1;
} else
if (!strcmp(argv[i],"-vv")) {
verbose = 2;
} else
if (!strcmp(argv[i],"-i")) {
print_info(0);
} else
if ((!strcmp(argv[i],"-h")) || (!strcmp(argv[1],"-?"))) {
print_help(0);
} else
if (!strcmp(argv[i],"-a")) {
subnet = 1;
} else
if (!strcmp(argv[i],"-s")) {
strobe = 1;
} else
if (!strcmp(argv[i],"-b")) {
if ((i+1) > (argc - 1)) {
print_usage(1);
} else {
base_port = (u_short)atoi(argv[i+1]);
i++;
}
} else
if (!strcmp(argv[i],"-e")) {
if ((i+1) > (argc - 1)) {
print_usage(1);
} else {
end_port = (u_short)atoi(argv[i+1]);
i++;
}
} else
if (!strcmp(argv[i],"-bm")) {
if ((i+1) > (argc - 1)) {
print_usage(1);
} else {
start_address = (u_char)atoi(argv[i+1]);
i++;
}
} else
if (!strcmp(argv[i],"-em")) {
if ((i+1) > (argc - 1)) {
print_usage(1);
} else {
end_address = (u_char)atoi(argv[i+1]);
i++;
}
}
}
}
if ((base_port > end_port) || ((short)base_port < 0)) {
fprintf(stderr,"Bad port range : start=%d end=%d !\n", base_port, end_port);
exit(1);
}
if ((start_address > end_address)) {
fprintf(stderr,"Bad address range : start=%d end=%d !\n", start_address, end_address);
exit(1);
}
if (subnet) printf("Subnet scanning enabled\n");
bzero((char *)&address, sizeof(address));
address.sin_family = AF_INET;
strncpy(addr,argv[argc - 1],1023);
addr[1023] = 0;
if (verbose == 2) printf("Resolving: %s ->",addr);
if ((host_info = gethostbyname(addr)))
{
bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
if (verbose == 2) printf(" resolved\n");
}
else if ((address.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE)
{
fprintf(stderr,"Could not get %s host entry !\n",argv[1]);
printf(" NOT resolved !!!\n");
exit(1);
}
else if (verbose == 2) printf(" address valid\n");
if (subnet) {
if (verbose == 2) printf("Starting SUBNET port scanning\n");
for (i=start_address; i <= end_address; i++) {
sub_address = (struct sockaddr *)&address;
sub_address->sa_data[5] = i;
if (verbose == 2) printf("Current address: ");
printf("%d.%d.%d.%d\n",(u_char)sub_address->sa_data[2],(u_char)sub_address->sa_data[3],
(u_char)sub_address->sa_data[4],(u_char)sub_address->sa_data[5]);
bcopy(sub_address,&address2,sizeof(address2));
if (verbose == 2) {
printf("Port range: %d to %d\n",base_port,end_port);
}
port_scan();
printf("#\n");
}
if (verbose == 2) printf("SUBNET scanning completed\n");
} else {
sub_address = (struct sockaddr *)&address;
if (verbose == 2) printf("Current address: ");
printf("%d.%d.%d.%d\n",(u_char)sub_address->sa_data[2],(u_char)sub_address->sa_data[3],
(u_char)sub_address->sa_data[4],(u_char)sub_address->sa_data[5]);
bcopy(sub_address,&address2,sizeof(address2));
if (verbose == 2) {
printf("Port range: %d to %d\n",base_port,end_port);
}
port_scan();
printf("#\n");
}
exit(0);
}
void port_scan(void) {
int finished = 0; /* Set to 1 when strobe scanning is finished */
int goodproto = 0; /* set to 1 if protocol returned in service info structure can be scanned */
if ((strobe) && (verbose == 2)) {
printf("Strobe scanning started...\n");
setservent(1);
}
while (((base_port + current_port) <= end_port) || !finished) {
/* fprintf(stderr,"Trying port: %d\n",base_port+current_port); */
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
// fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
fprintf(stderr, "Error assigning master socket: sys_errlist[errno]\n");
exit(-1);
}
if (strobe) {
while(!goodproto) {
service_info = getservent();
if (!service_info) break;
if (!strcmp(service_info->s_proto,"tcp") && (ntohs(service_info->s_port) <= end_port) && (ntohs(service_info->s_port) >= base_port)) {
goodproto = 1;
break;
}
}
if (!goodproto) break;
if (!service_info) {
finished = 1;
break;
}
if (goodproto) address2.sin_port = service_info->s_port;
goodproto = 0;
} else address2.sin_port = htons(base_port+current_port);
if (!finished)
if (connect(sock, (struct sockaddr *)&address2, sizeof(address2)) == 0) {
switch (verbose) {
case 0: if (strobe)
printf("%d\n",ntohs(service_info->s_port));
else
printf("%d\n",base_port+current_port);
break;
case 1: if (!strobe) {
service_info = getservbyport(htons(base_port+current_port),"tcp");
if (!service_info) {
printf("%d -> service name unknown\n",base_port+current_port);
} else {
printf("%d -> %s\n",base_port+current_port,service_info->s_name);
}
} else printf("%d -> %s\n",ntohs(service_info->s_port),service_info->s_name);
break;
case 2: if (!strobe) {
service_info = getservbyport(htons(base_port+current_port),"tcp");
if (!service_info) {
printf("Port %d found. Service name unknown\n",base_port+current_port);
} else {
printf("Port %d found. Service name: %s\n",base_port+current_port,service_info->s_name);
}
} else {
printf("Port %d found. Service name: %s\n",ntohs(service_info->s_port),service_info->s_name);
}
break;
}
} else if (errno == 113) {
fprintf(stderr,"No route to host !\n");
if (!subnet) {
close(sock);
exit(1);
}
}
/* fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
errno,sock,base_port+current_port,sys_errlist[errno]); */
close(sock);
current_port++;
if (base_port+current_port >= end_port) {
finished = 1;
}
/* fprintf(stderr,"current_port: %d,b: %d,e:%d,b+c:%d\n", current_port, base_port,end_port,base_port+current_port); */
}
if (verbose == 2) printf("Port scan finished !\n");
if (strobe) endservent();
}